package com.lam.schedule.common.scheduler.model;

import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.lam.common.exception.BaseException;
import com.lam.common.utils.DateUtil;
import com.lam.common.utils.JsonUtil;
import com.lam.common.utils.SpringUtils;
import com.lam.common.utils.uuid.IdUtils;
import com.lam.schedule.common.constant.ScheduleConstant;
import com.lam.schedule.common.scheduler.util.InvokeUtils;
import com.lam.schedule.entity.ScheduleJob;
import com.lam.schedule.entity.ScheduleJobLog;
import com.lam.schedule.service.ScheduleJobLogService;

public abstract class AsyncJob{
	
	private final Logger logger = LoggerFactory.getLogger(getClass());
	
	protected void runJob(ScheduleJob scheduleJob, Map<String, Object> exeParam, ScheduleJobLog jobLog) {
		
		String uid = IdUtils.getUid();
		logger.info("任务开始执行, uid：{}, jobName：{}, param:{}, exeParam:{}, cron:{}, cronDesc:{}", uid, scheduleJob.getJobName(), 
				scheduleJob.getExeParam(), JsonUtil.toString(exeParam), scheduleJob.getCronExpression(), scheduleJob.getCronExpDesc());
		if(jobLog.collectLog()) {
			SpringUtils.getBean(ScheduleJobLogService.class).insert(jobLog);
		}
		long startTime = System.currentTimeMillis();
		
		try {
			InvokeUtils.invokeJob(scheduleJob, exeParam);
			setExeResult(jobLog, ScheduleConstant.EXE_STATUS_SUCCESS, "执行成功！");
		} catch (BaseException e) {
			logger.error("执行任务失败, uid:{}, error:{}", uid, e.getMessage());
			setExeResult(jobLog, ScheduleConstant.EXE_STATUS_FAIL, e.getMessage());
			throw e;
		} catch (Exception e) {
			logger.error("执行任务异常, uid:" + uid, e);
			setExeResult(jobLog, ScheduleConstant.EXE_STATUS_FAIL, "执行任务异常：" + e.getMessage());
			throw e;
		} finally{
			updateLog(exeParam, jobLog);
			logger.info("任务执行结束, uid：{}, cost: {}", uid, DateUtil.convertTimeLong(System.currentTimeMillis()-startTime));
		}
	}

	protected static ScheduleJobLog getJobLog(ScheduleJob scheduleJob, Map<String, Object> exeParam) {
		ScheduleJobLog jobLog = (ScheduleJobLog)JsonUtil.get(exeParam, ScheduleConstant.CUR_EXE_LOG);
		if(jobLog == null) {
			jobLog = new ScheduleJobLog(scheduleJob, ScheduleConstant.TRIGGER_TYPE_TIMER).start();
			jobLog.setCreateBy(ScheduleConstant.TRIGGER_USER);
		}
		return jobLog;
	}
	
	protected static void updateLog(Map<String, Object> exeParam, ScheduleJobLog jobLog) {
		if(jobLog != null && jobLog.collectLog()) {
			SpringUtils.getBean(ScheduleJobLogService.class).updateResult(jobLog.calcCost());
		}
	}
	
	protected static void setExeResult(ScheduleJobLog jobLog, Integer exeStatus, String exeMsg) {
		jobLog.setExeStatus(exeStatus);
		jobLog.setExeMsg(exeMsg);
	}

}
